#include "ImageCompressTool.h"

ImageCompressTool::ImageCompressTool(QWidget* parent)
	: CommonGraphicsView{ parent }
{
	this->setWindowTitle("图片压缩");
	this->setFixedSize(QSize(320, 800));
	QVBoxLayout* vLayout = new QVBoxLayout(this);

	QHBoxLayout* hLayout = new QHBoxLayout(this);
	EditText* et = new EditText(this);
	et->setEnabled(false);
	et->setFixedHeight(30);
	Button* btnChoiceBtn = new Button(this);
	btnChoiceBtn->setText("请选择图片");


	hLayout->addWidget(et);
	hLayout->addWidget(btnChoiceBtn);
	hLayout->setAlignment(Qt::AlignTop);

	QHBoxLayout* radioTypeHLayout = new QHBoxLayout(this);
	QButtonGroup* group = new QButtonGroup(this);
	QRadioButton* radioButtonJPEG = new QRadioButton("JPEG", this);
	radioButtonJPEG->setFixedSize(60, 30);
	QRadioButton* radioButton2PNG = new QRadioButton("PNG", this);
	radioButton2PNG->setFixedSize(60, 30);
	group->addButton(radioButtonJPEG, 1);
	group->addButton(radioButton2PNG, 2);
	radioTypeHLayout->addWidget(radioButtonJPEG);
	radioTypeHLayout->addWidget(radioButton2PNG);
	radioTypeHLayout->setAlignment(Qt::AlignLeft);

	//图片质量（JPEG）
	qualitLabel = new QLabel(this);
	qualitLabel->setText("图片质量：" + QString::number(mKsize));
	qualitLabel->setFixedHeight(15);
	//显示原图大小（KB）
	srcImageKb = new QLabel(this);
	srcImageKb->setText("原图大小：");
	srcImageKb->setFixedHeight(15);
	//显示压缩后图片大小（KB）
	compressImageKb = new QLabel(this);
	compressImageKb->setText("压缩后图片大小：");
	compressImageKb->setFixedHeight(15);
	//开始压缩按钮
	Button* startCompressBtn = new Button(this);
	startCompressBtn->resize(60, 30);
	startCompressBtn->setText("开始压缩");

	//测试选择多张图一起压缩，选中后直接压缩即可
	Button* startCompressMultiBtn = new Button(this);
	startCompressMultiBtn->resize(60, 30);
	startCompressMultiBtn->setText("请选择需要压缩的图片（多张）");


	QLabel* comBoxLabel = new QLabel(this);
	comBoxLabel->setText("请选择图片质量：");
	comBoxLabel->setFixedHeight(15);
	//ComBox选择图片质量
	comBox = new ComboBox(this);
	for (int i = 10;i <= 100;i += 10) {
		comBox->addItem(QString::number(i));
	}
	QHBoxLayout* comBoxHLayout2 = new QHBoxLayout(this);
	comBoxHLayout2->addWidget(comBoxLabel);
	comBoxHLayout2->addWidget(comBox);

	imageViewResult = new QLabel(this);

	vLayout->addLayout(hLayout);
	vLayout->addLayout(radioTypeHLayout);
	//vLayout->addWidget(imageViewSrc);
	vLayout->addWidget(imageViewResult);
	vLayout->setAlignment(Qt::AlignTop);

	vLayout->addWidget(qualitLabel);
	vLayout->addWidget(srcImageKb);
	vLayout->addWidget(compressImageKb);
	vLayout->addLayout(comBoxHLayout2);
	vLayout->addWidget(startCompressBtn);
	vLayout->addWidget(startCompressMultiBtn);
	this->setLayout(vLayout);

	connect(btnChoiceBtn, &Button::clicked, this, [=]() {
		QFileInfo fileInfo;
		filePath = QFileDialog::getOpenFileName(this, tr("请选择图片"), "C:/Users/DBF-DEV-103/Downloads/", tr("Image Files(*.jpg *.png  *.jpeg)"));
		et->setText(filePath);
		fileInfo = QFileInfo(filePath);
		//获取文件后缀名
		QString  fileSuffix = fileInfo.suffix();
		qDebug() << "文件的后缀名为:" << fileSuffix;
		if (fileSuffix == "jpeg" || fileSuffix == "jpg") {
			imageType = 0;
			radioButtonJPEG->setChecked(true);
			comBox->clear();
			for (int i = 10;i <= 100; i += 10) {
				comBox->addItem(QString::number(i));
			}
		}
		else if (fileSuffix == "png") {
			imageType = 1;
			radioButton2PNG->setChecked(true);
			comBox->clear();
			for (int i = 0;i <= 10; i++) {
				comBox->addItem(QString::number(i));
			}
		}
		//compressImage();
		});


	//选择了JPEG
	connect(radioButtonJPEG, &QRadioButton::clicked, this, [=]() {
		imageType = 0;
		qDebug() << "图片类型" << imageType;
		});
	//选择了PNG
	connect(radioButton2PNG, &QRadioButton::clicked, this, [=]() {
		imageType = 1;
		qDebug() << "图片类型：" << imageType;
		});

	//开始压缩按钮信号槽（点击事件）
	connect(startCompressBtn, &Button::clicked, this, [=]() {
		compressImage();

		});

	//选择图片质量信号槽
	connect(comBox, &ComboBox::currentTextChanged, [=](const QString value) {
		qDebug() << "选择的value值：" << value;
		mKsize = value.toInt();
		qualitLabel->setText("图片质量：" + QString::number(mKsize));
		});


	//选择多张图压缩点击事件
	connect(startCompressMultiBtn, &Button::clicked, this, [=]() {
		QStringList list = QFileDialog::getOpenFileNames(this, tr("请选择多个文件"), "C:/Users/DBF-DEV-103/Downloads/", tr("Images (*.jpg *.png)"));
		for (QString filePath : list) {
			qDebug() << "filePath:" << filePath;
		}
		filePaths = list;
		compressImages();
		});

}
//压缩图片
void ImageCompressTool::compressImage() {
	if (this->filePath == NULL) {
		QMessageBox::information(this, "温馨提示", "请选择要压缩的图片");
		return;
	}
	cv::Mat src = cv::imread(this->filePath.toStdString().c_str());
	//imshow("src", src);
	double srcKb = matSizeInKB(filePath.toStdString());
	srcImageKb->setText("原图大小：" + QString::number(srcKb));
	std::cout << "原图大小:" << srcKb << std::endl;
	std::vector<int> compression_params;
	if (imageType == 0) {
		compression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
		//压缩级别范围从0~100，值越小压缩率越高，即在磁盘占用的空间越小，相应的图片的质量越差
		compression_params.push_back(mKsize);
	}
	else {
		compression_params.push_back(cv::IMWRITE_PNG_COMPRESSION);
		if (mKsize > 10) {
			mKsize = 3;
		}
		compression_params.push_back(mKsize); // 压缩级别范围从0到9，9是最高压缩
	}
	//将图片以jpg的格式存入文件
	char* compressImgPath = "E://opencv_compress_img.jpeg";
	if (imageType == 1) {
		compressImgPath = "E://opencv_compress_img.png";
	}
	bool result = cv::imwrite(compressImgPath, src, compression_params);
	if (!result) {
		std::cout << "压缩图片失败" << endl;
		return;
	}
	QFile compressFile = QFile(compressImgPath);
	double compressSizeKb = matSizeInKB(compressImgPath);
	compressImageKb->setText("压缩后的图片大小：" + QString::number(compressSizeKb));
	std::cout << "压缩后的图片大小为：" << compressSizeKb << std::endl;
	std::cout << "压缩图片成功,存储路径为：" << compressImgPath << std::endl;
}

//一次性压缩多张图片
void ImageCompressTool::compressImages() {
	if (this->filePaths.empty()) {
		QMessageBox::information(this, "温馨提示", "请选择图片");
		return;
	}
	int index = 0;
	for (QString mFilePath : this->filePaths) {
		QFileInfo fileInfo = QFileInfo(mFilePath);
		//获取文件后缀名
		QString  fileSuffix = fileInfo.suffix();
		qDebug() << "文件的后缀名为:" << fileSuffix;
		if (fileSuffix == "jpeg" || fileSuffix == "jpg") {
			imageType = 0;
			this->mKsize = 30;
		}
		else if (fileSuffix == "png") {
			imageType = 1;
			this->mKsize = 9;
		}
		cv::Mat src = cv::imread(mFilePath.toStdString().c_str());
		double srcKb = matSizeInKB(mFilePath.toStdString());
		std::vector<int> compression_params;
		if (imageType == 0) {
			compression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
			//压缩级别范围从0~100，值越小压缩率越高，即在磁盘占用的空间越小，相应的图片的质量越差
			compression_params.push_back(mKsize);
		}
		else {
			compression_params.push_back(cv::IMWRITE_PNG_COMPRESSION);
			if (mKsize > 10) {
				mKsize = 3;
			}
			compression_params.push_back(mKsize); // 压缩级别范围从0到9，9是最高压缩
		}
		//将图片以jpg的格式存入文件
		QString compressImgPath = "E://";
		//char* compressImgPath = "E://opencv_compress_img.jpeg";
		if (imageType == 1) {
			compressImgPath.append("opencv_compress_img").append("(").append(QString::number(index + 1)).append(")").append(".png");
		}
		else {
			compressImgPath.append("opencv_compress_img").append("(").append(QString::number(index + 1)).append(")").append(".jpeg");
		}
		bool result = cv::imwrite(compressImgPath.toStdString().c_str(), src, compression_params);
		if (!result) {
			qDebug() << "压缩图片失败";
			return;
		}
		double compressSizeKb = matSizeInKB(compressImgPath.toStdString().c_str());
		qDebug() << "(" << index + 1 << ")" << "压缩前：" << srcKb << "KB:" << mFilePath;
		qDebug() << "(" << index + 1 << ")" << "压缩后：" << compressSizeKb << "KB:" << compressImgPath;
		index++;
	}


}

long ImageCompressTool::matSizeInKB(std::string filePath) {
	std::ifstream mFile(filePath, std::ifstream::binary);
	if (mFile) {
		mFile.seekg(0, mFile.end);
		long size = mFile.tellg(); // 获取文件大小（字节）
		mFile.close();
		return size / 1024; // 转换为KB
	}
	return -1; // 文件打开失败，返回-1
}

ImageCompressTool::~ImageCompressTool()
{
}
